<!--
 * @Descripttion: 课堂分析详情-教师行为-授课时间
 * @version: V1.0.0.1
 * @Author: zhaozhenzhuo
 * @Date: 2025-10-27 10:09:06
 * @LastEditors: zhaozhenzhuo
 * @LastEditTime: 2025-10-27 10:09:06
-->
<template>
	<div class="teaching-time-wrapper">
		<template v-if="type === 1">
			<div class="module-title-wrapper">
				<p>授课时间</p>
				<img v-if="false" src="@/assets/images/lessonAnalysisDetails/text-edit-normal.png" />
			</div>
			<div class="detail">
				<p>
					本堂课计划<span v-if="lessonInfo?.planBeginTime" class="active">{{
						formatTime(lessonInfo?.planBeginTime, 'HH:mm')
					}}</span
					><span v-else class="active">-</span>上课，实际于<span
						v-if="aiScoreResult?.calBeginTime"
						:class="{
							active: !aiScoreResult?.abnormalType || aiScoreResult?.abnormalType[0] !== '1',
							red: aiScoreResult?.abnormalType && aiScoreResult?.abnormalType[0] === '1'
						}"
						>{{ formatTime(aiScoreResult?.calBeginTime, 'HH:mm') }}</span
					><span v-else class="active">-</span>上课<span
						v-if="aiScoreResult?.abnormalType && aiScoreResult?.abnormalType[0] === '1'"
						>，迟到<span class="red"
							>{{ Math.floor((aiScoreResult?.calLateBeginTime || 0) / 60000) }}分钟</span
						></span
					>。计划上课<span v-if="aiScoreResult?.planTotalTime || aiScoreResult?.planTotalTime === 0"
						>{{ Math.floor(aiScoreResult?.planTotalTime / 60000) }}分钟</span
					><span v-else>-分钟</span>，共上<span
						v-if="aiScoreResult?.calTotalTime || aiScoreResult?.calTotalTime === 0"
						>{{ Math.floor(aiScoreResult?.calTotalTime / 60000) }}分钟</span
					><span v-else>-分钟</span>，其中老师讲课时长<span
						v-if="aiScoreResult?.teachTime || aiScoreResult?.teachTime === 0"
						>{{ Math.floor((aiScoreResult?.calTeachTime || 0) / 60000) }}分钟</span
					><span v-else>-分钟</span>，占比<span
						v-if="
							(aiScoreResult?.teachTime || aiScoreResult?.teachTime === 0) &&
							aiScoreResult?.calTotalTime
						"
						class="active"
						>{{
							(aiScoreResult?.calTeachTime || 0) / (aiScoreResult?.calTotalTime || 0) >= 1
								? 100
								: (
										(100 * (aiScoreResult?.calTeachTime || 0)) /
										(aiScoreResult?.calTotalTime || 0)
								  ).toFixed(1)
						}}%</span
					><span v-else class="active">-%</span>，最长连续讲课<span
						v-if="aiScoreResult?.longTeachTime || aiScoreResult?.longTeachTime === 0"
						class="active"
						>{{ Math.floor(aiScoreResult?.longTeachTime / 60000) }}分钟</span
					><span v-else class="active">-分钟</span>。计划<span
						v-if="lessonInfo?.planEndTime"
						class="active"
						>{{ formatTime(lessonInfo?.planEndTime, 'HH:mm') }}</span
					><span v-else class="active">-</span>下课，实际于<span
						v-if="aiScoreResult?.calEndTime"
						:class="{
							active:
								!aiScoreResult?.abnormalType ||
								(aiScoreResult?.abnormalType[1] !== '1' && aiScoreResult?.abnormalType[2] !== '1'),
							red:
								aiScoreResult?.abnormalType &&
								(aiScoreResult?.abnormalType[1] === '1' || aiScoreResult?.abnormalType[2] === '1')
						}"
						>{{ formatTime(aiScoreResult?.calEndTime, 'HH:mm') }}</span
					><span v-else class="active">-</span>下课<span
						v-if="
							aiScoreResult?.abnormalType &&
							aiScoreResult?.abnormalType[1] === '1' &&
							aiScoreResult?.calBeginTime &&
							aiScoreResult?.calEndTime
						"
						>，提前下课<span class="red"
							>{{
								(aiScoreResult?.calEarlyStopTime || 0) / 60000 +
								((aiScoreResult?.planBreakTime || 0) / 60000 -
									(aiScoreResult?.realBreakTime || 0) / 60000 >
								0
									? (aiScoreResult?.planBreakTime || 0) / 60000 -
									  (aiScoreResult?.realBreakTime || 0) / 60000
									: 0)
							}}分钟</span
						>，由于本堂课<span v-if="!aiScoreResult?.planBreakTime">无课间</span
						><span v-else-if="!aiScoreResult?.realBreakTime"
							>课间{{ aiScoreResult?.planBreakTime / 60000 }}分钟未休息</span
						><span v-else-if="aiScoreResult?.realBreakTime < aiScoreResult?.planBreakTime"
							>课间{{ aiScoreResult?.planBreakTime / 60000 }}分钟中实际休息{{
								aiScoreResult?.realBreakTime / 60000
							}}分钟</span
						><span v-else>课间{{ aiScoreResult?.planBreakTime / 60000 }}分钟正常休息</span
						>，实际<span
							>早退<span class="red"
								>{{ (aiScoreResult?.calEarlyStopTime || 0) / 60000 }}分钟</span
							></span
						></span
					><span
						v-else-if="
							aiScoreResult?.abnormalType &&
							aiScoreResult?.abnormalType[2] === '1' &&
							aiScoreResult?.calBeginTime &&
							aiScoreResult?.calEndTime
						"
						>，拖堂<span class="red"
							>{{ Math.floor((aiScoreResult?.calLateStopTime || 0) / 60000) }}分钟</span
						></span
					>。
				</p>
			</div>
			<!-- 老师讲授canvas -->
			<div class="box-wrap">
				<div class="voice-canvas-wrap">
					<p class="in-class">上课</p>
					<div class="canvas-content"></div>
					<p class="out-class">下课</p>
				</div>
			</div>
		</template>
		<template v-else>
			<div class="canvas-wrap">
				<div class="title-wrap">
					<div class="line"></div>
					<p>课堂讲授/学生发言时间分布</p>
				</div>
				<div v-if="audioTaskTimeTableData?.length">
					<!-- 课堂讲授canvas -->
					<div class="teach-canvas-wrap">
						<p class="left">课堂讲授</p>
						<div class="teach-canvas-content"></div>
					</div>
					<!-- 问答互动canvas -->
					<div class="interaction-canvas-wrap">
						<p class="left">学生发言</p>
						<div class="interaction-canvas-content">
							<!-- 时间线 -->
							<div
								v-for="(item, index) in teachTimeLineList"
								:key="index"
								:class="['timeline-item', `timeline-item-${index}`]"
							>
								<span v-if="item">{{ formatTime(item, 'HH:mm') }}</span
								><span v-else>-:-</span>
							</div>
						</div>
					</div>
				</div>
				<div v-else>
					<p class="empty-detail">
						<span class="empty-wrap">本堂课未识别到教师/学生发言</span>
					</p>
				</div>
			</div>
		</template>
	</div>
</template>

<script setup lang="ts">
import { ref, computed, watch, nextTick, onMounted, onUnmounted } from 'vue';
import { formatTime } from '@/assets/js/utils';
import DrawHorizontalAreaCanvas from '@/assets/js/drawHorizontalAreaCanvas';
import { getErrorMessage, getAudioTaskTimeTableAPI } from '@/api/index';
import type {
	CourseListItemType,
	AnalysisResultType,
	TimeTableListItemType,
	EventLineItemType,
	AudioTaskTimeTableItemType,
	BreakInfoType,
	FormatBreakInfoType,
	DurationInfoType,
	BlockInfoType
} from './TeachingTime.type';

const props = withDefaults(
	defineProps<{
		type: 1 | 2;
		queryObj: {
			lessonInfo: CourseListItemType | null;
			aiScoreResult: AnalysisResultType | null;
			offsetTime: number;
			videoBeginTime: number;
		} | null;
		timeTableList: TimeTableListItemType[] | null;
		eventTimeLineList: EventLineItemType[] | null;
	}>(),
	{
		type: 1, // 1:老师数据 2:学生数据
		queryObj: null,
		timeTableList: null,
		eventTimeLineList: null
	}
);

const lessonInfo = computed(() => props.queryObj?.lessonInfo);
const aiScoreResult = computed(() => props.queryObj?.aiScoreResult);
const videoBeginTime = computed(() => props.queryObj?.videoBeginTime);

watch(
	() => props.queryObj,
	(newVal) => {
		if (newVal) {
			nextTick(() => {
				getAudioTaskTimeTable();
			});
		}
	},
	{ immediate: true }
);

const emit = defineEmits<{
	(e: 'changeVideoTime', time: number): void; // 切换视频时间
}>();

// 授课时间模块canvas实例
const canvasContent = ref<DrawHorizontalAreaCanvas | null>(null);
// 课堂讲授canvas实例
const teachCanvasContent = ref<DrawHorizontalAreaCanvas | null>(null);
// 学生发言canvas实例
const interactionCanvasContent = ref<DrawHorizontalAreaCanvas | null>(null);

// 窗口大小与1920的比值
const rate = ref(
	(window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) / 1920
);

onMounted(() => {
	window.addEventListener('resize', resizeHandler);
});

onUnmounted(() => {
	// 清除绑定的事件
	if (canvasContent.value) {
		canvasContent.value.removeCanvasBindEvent();
		canvasContent.value.removeCanvasBindClickEvent();
	}
	if (teachCanvasContent.value) {
		teachCanvasContent.value.removeCanvasBindEvent();
		teachCanvasContent.value.removeCanvasBindClickEvent();
	}
	if (interactionCanvasContent.value) {
		interactionCanvasContent.value.removeCanvasBindEvent();
		interactionCanvasContent.value.removeCanvasBindClickEvent();
	}
	window.removeEventListener('resize', resizeHandler);
});

const resizeHandler = () => {
	setTimeout(() => {
		rate.value =
			(window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth) /
			1920;

		// 清除旧的canvas实例和事件监听
		if (canvasContent.value) {
			canvasContent.value.removeCanvasBindEvent();
			canvasContent.value.removeCanvasBindClickEvent();
			canvasContent.value = null;
		}
		if (teachCanvasContent.value) {
			teachCanvasContent.value.removeCanvasBindEvent();
			teachCanvasContent.value.removeCanvasBindClickEvent();
			teachCanvasContent.value = null;
		}
		if (interactionCanvasContent.value) {
			interactionCanvasContent.value.removeCanvasBindEvent();
			interactionCanvasContent.value.removeCanvasBindClickEvent();
			interactionCanvasContent.value = null;
		}

		// 清除所有areaCanvasWrap元素（包括其中的canvas、矩形块、tooltip等所有内容）
		const areaCanvasWrapRef = document.querySelectorAll('.area-canvas-wrap');
		if (areaCanvasWrapRef.length) {
			areaCanvasWrapRef.forEach((areaCanvasWrap) => {
				areaCanvasWrap.remove();
			});
		}

		// 使用 nextTick 确保 DOM 清除完成后再重新创建
		nextTick(() => {
			// 根据type重新创建画布和绘制矩形块
			if (props.type === 1) {
				// 重新初始化授课时间模块canvas
				const canvasContentDom = document.querySelector('.canvas-content');
				if (canvasContentDom) {
					canvasContent.value = new DrawHorizontalAreaCanvas(canvasContentDom as HTMLDivElement);
					canvasContent.value.createCanvas({
						'border-radius': '1px',
						'background-color': 'rgba(0, 168, 255, 0.1)',
						cursor: 'pointer'
					});
					// 重新绘制
					initOffset();
					initTimeLine();
					initBreakOffset();
					initRealBreakOffset();
					// 重新绘制授课时长图表
					if (durationChartList1.value.length) {
						initTeachingDurationChart();
					}
				}
			} else if (props.type === 2) {
				// 重新绘制图表
				if (durationChartList.value.length) {
					initDurationChart(0); // 绘制老师
					initDurationChart(1); // 绘制学生
				}
				// 重新设置时间线位置
				setTimelinePosition();
			}
		});
	}, 300);
};

// 授课时长时间线，开始时间是课表上的计划开始时间；结束时间分两种情况，如果准时或提前下课，结束时间是课表计划结束时间，如果延迟下课，结束时间是实际结束时间
const teachTimeLineList = ref<number[]>([]);
// 计算授课时长时间线
const initTimeLineList = () => {
	const _beginTime = lessonInfo.value?.planBeginTime;
	const _endTime = lessonInfo.value?.planEndTime;
	const _splitTime = ((_endTime || 0) - (_beginTime || 0)) / 6;
	teachTimeLineList.value = [];
	for (let i = 0; i < 7; i++) {
		if (i !== 6) {
			teachTimeLineList.value.push((_beginTime || 0) + i * _splitTime);
		} else {
			// 提前下课或准时下课
			teachTimeLineList.value.push(_endTime || 0);
		}
	}
	// 计算时间线中每项的位置
	nextTick(() => {
		setTimelinePosition();
	});
};

// 授课时长的偏移量
const teachingOffsetTime = ref<number>(0);
// 授课时长的总时长
const teachingTotalTime = ref<number>(0);
// 授课时长的计划开始时间
const teachingPlanBeginTime = ref<number>(0);
// 设置时间线的位置
const setTimelinePosition = () => {
	const _interactionCanvasRef = document.querySelector('.interaction-canvas-content');
	if (_interactionCanvasRef) {
		const _width = _interactionCanvasRef.clientWidth;
		teachTimeLineList.value.forEach((item, index) => {
			const _left =
				((item - teachingPlanBeginTime.value) / teachingTotalTime.value) * (_width || 0);
			const timelineItemRef: HTMLDivElement | null = document.querySelector(
				`.interaction-canvas-content .timeline-item-${index}`
			);
			if (timelineItemRef) {
				timelineItemRef.style.left = `${_left}px`;
			}
		});
	}
};

// 时间线数据
const audioTaskTimeTableData = ref<AudioTaskTimeTableItemType[] | null>([]);
// 根据语音转写结果获取课堂讲课时间轴
const getAudioTaskTimeTable = async () => {
	if (props.type === 1) {
		// 初始化实例
		canvasContent.value = new DrawHorizontalAreaCanvas(document.querySelector('.canvas-content'));
		// 创建画布
		canvasContent.value.createCanvas({
			'border-radius': '1px',
			'background-color': 'rgba(0, 168, 255, 0.1)',
			cursor: 'pointer'
		});
	}

	initTimeLineList();
	let _offsetTime = 0;
	let _totalTime = 0;
	let _videoBeginTime = 0;
	// 如果实际上课时间小于规定上课时间，则使用实际上课时间
	const _planBeginTime =
		aiScoreResult.value?.beginTime &&
		lessonInfo.value?.planBeginTime &&
		aiScoreResult.value?.beginTime < lessonInfo.value?.planBeginTime
			? aiScoreResult.value?.beginTime
			: lessonInfo.value?.planBeginTime;
	// 计算偏移时间
	if (_planBeginTime && videoBeginTime.value) {
		_videoBeginTime =
			_planBeginTime - videoBeginTime.value < 0 ? _planBeginTime : videoBeginTime.value;
		_offsetTime = _planBeginTime - _videoBeginTime;
	}
	// 计算总时长
	if (
		aiScoreResult.value?.abnormalType &&
		aiScoreResult.value?.abnormalType[2] === '1' &&
		aiScoreResult.value?.endTime &&
		_videoBeginTime
	) {
		// 延迟下课
		_totalTime = aiScoreResult.value?.endTime - _videoBeginTime - _offsetTime;
	} else if (lessonInfo.value?.planEndTime && _videoBeginTime) {
		// 提前下课或准时下课
		_totalTime = lessonInfo.value?.planEndTime - _videoBeginTime - _offsetTime;
	}
	// 保存“授课时间”模块的偏移时间和总时长
	teachingOffsetTime.value = _offsetTime;
	teachingTotalTime.value = _totalTime;
	teachingPlanBeginTime.value = _planBeginTime || 0;
	// 计算开始上课和下课的偏移量
	initOffset();
	// 计算时间线的偏移量
	initTimeLine();
	// 计算计划课间时间的偏移量
	initBreakOffset();
	// 计算实际课间休息时间的偏移量
	initRealBreakOffset();

	// 获取时间轴信息
	try {
		const data = await getAudioTaskTimeTableAPI({
			businessCode: lessonInfo.value?.code as string,
			timeInterval: 2000
		});

		if (!data?.length) {
			audioTaskTimeTableData.value = null;
			return;
		}
		audioTaskTimeTableData.value = data;
		// 将时间的字符串转为数字
		data.forEach((item) => {
			item.bg = Number(item.bg);
			item.ed = Number(item.ed);
		});

		if (props.type === 1) {
			// 初始化授课数据
			initTeachingData(JSON.parse(JSON.stringify(data)));
		} else {
			// 初始化互动数据
			initInteractionData(JSON.parse(JSON.stringify(data)));
		}
	} catch (err) {
		console.error(getErrorMessage(err));
	}
};

// 计算开始上课和下课的偏移量
const initOffset = () => {
	if (!document.querySelector('.canvas-content')) {
		return;
	}
	const _width = document.querySelector('.canvas-content')?.clientWidth;
	// 上课
	const _beginLeft =
		((aiScoreResult.value?.lateBeginTime || 0) / teachingTotalTime.value) * (_width || 0) || 0;
	const _beginDom = `
				<div
					class="begin-time ${
						aiScoreResult.value?.abnormalType && aiScoreResult.value?.abnormalType[0] === '1'
							? 'red'
							: 'blue'
					} ${aiScoreResult.value?.calBeginTime ? '' : 'hidden'}"
				>
					${
						/* eslint-disable no-nested-ternary */
						aiScoreResult.value?.abnormalType && aiScoreResult.value?.abnormalType[0] === '1'
							? '<p>延迟</p>'
							: aiScoreResult.value?.calBeginTime &&
							  lessonInfo.value?.planBeginTime &&
							  aiScoreResult.value?.calBeginTime < lessonInfo.value?.planBeginTime
							? '<p>提前</p>'
							: '<p>准点</p>'
					}
					${
						aiScoreResult.value?.calBeginTime
							? `<p>
						${formatTime(aiScoreResult.value?.calBeginTime, 'HH:mm')}
					</p>`
							: '<p>未知时间</p>'
					}
					<div class="circle"></div>
					<div class="line"></div>
				</div>
			`;
	// 渲染dom
	canvasContent.value?.renderDomAtSpecifiedPosition(_beginDom, _beginLeft, 0);

	// 下课
	/* eslint-disable no-nested-ternary */
	const _endDom = `
				<div
					class="end-time ${
						!aiScoreResult.value?.abnormalType ||
						(aiScoreResult.value?.abnormalType[1] !== '1' &&
							aiScoreResult.value?.abnormalType[2] !== '1')
							? 'blue'
							: 'red'
					} ${aiScoreResult.value?.calEndTime ? '' : 'hidden'}"
				>
					${
						aiScoreResult.value?.abnormalType && aiScoreResult.value?.abnormalType[1] === '1'
							? '<p>提前</p>'
							: aiScoreResult.value?.abnormalType && aiScoreResult.value?.abnormalType[2] === '1'
							? '<p>延迟</p>'
							: '<p>准点</p>'
					}
					${
						aiScoreResult.value?.calBeginTime
							? `<p>${formatTime(aiScoreResult.value?.calEndTime || 0, 'HH:mm')}</p>`
							: '<p>未知时间</p>'
					}
					<div class="circle"></div>
					<div class="line"></div>
				</div>
			`;
	if (aiScoreResult.value?.abnormalType && aiScoreResult.value?.abnormalType[1] === '1') {
		const _endLeft =
			((teachingTotalTime.value - aiScoreResult.value?.earlyStopTime) / teachingTotalTime.value) *
				(_width || 0) || 0;
		// 渲染dom
		canvasContent.value?.renderDomAtSpecifiedPosition(_endDom, _endLeft, 0);
	} else {
		const _endLeft = _width;
		// 渲染dom
		canvasContent.value?.renderDomAtSpecifiedPosition(_endDom, _endLeft || 0, 0);
	}
};

// 计算时间线的偏移量
const initTimeLine = () => {
	if (
		teachTimeLineList.value &&
		teachTimeLineList.value.length &&
		document.querySelector('.canvas-content')
	) {
		const _width = document.querySelector('.canvas-content')?.clientWidth;
		teachTimeLineList.value.forEach((item, index) => {
			// 上课
			const _left =
				((item - teachingPlanBeginTime.value) / teachingTotalTime.value) * (_width || 0) || 0;
			const _dom = `
						<div class="timeline-item timeline-item-${index}">
							<div class="line"></div>
							<div class="circle"></div>
							<p>${item ? formatTime(item, 'HH:mm') : '-:-'}</p>
						</div>
					`;
			// 渲染dom
			canvasContent.value?.renderDomAtSpecifiedPosition(_dom, _left, 0);
		});
	}
};

// 课间数组
const breakArr = ref<BreakInfoType[]>([]);
// 计算课间时间的偏移量
const initBreakOffset = () => {
	breakArr.value = [];
	if (lessonInfo.value?.beginOrder && lessonInfo.value?.endOrder) {
		for (let i = lessonInfo.value?.beginOrder; i < lessonInfo.value?.endOrder; i++) {
			for (let j = 0; j < (props.timeTableList?.length || 0); j++) {
				if (
					props.timeTableList?.[j].classOrder === i &&
					props.timeTableList?.[j].endTime &&
					props.timeTableList?.[j + 1] &&
					props.timeTableList?.[j + 1].beginTime
				) {
					// 获取当天的日期
					const _date = formatTime(lessonInfo.value?.planBeginTime, 'YYYY-MM-DD');
					const _beginTime = new Date(`${_date} ${props.timeTableList?.[j].endTime}`).getTime();
					const _endTime = new Date(`${_date} ${props.timeTableList?.[j + 1].beginTime}`).getTime();
					const _width = document.querySelector('.canvas-content')?.clientWidth || 0;
					const _beginOffset =
						((_beginTime - teachingPlanBeginTime.value) / teachingTotalTime.value) * _width;
					const _endOffset =
						((_endTime - teachingPlanBeginTime.value) / teachingTotalTime.value) * _width;
					if (
						_beginOffset >= 0 &&
						_beginOffset <= _width &&
						_endOffset >= 0 &&
						_endOffset <= _width
					) {
						breakArr.value.push({
							time: _beginTime,
							offset: _beginOffset,
							type: 0 // 开始
						});
						breakArr.value.push({
							time: _endTime,
							offset: _endOffset,
							type: 1 // 结束
						});
					}
				}
			}
		}
	}
};

// 实际课间数组
const realBreakArr = ref<BreakInfoType[]>([]);
// 格式化后方便渲染的实际课间数组
const formatBreakArr = ref<FormatBreakInfoType[]>([]);
// 计算实际课间休息时间的偏移量
const initRealBreakOffset = () => {
	realBreakArr.value = [];
	props.eventTimeLineList?.forEach((event) => {
		if (
			(event.eventType === 1004 || event.eventType === 1005) &&
			videoBeginTime.value &&
			(event.eventTime || event.eventTime === 0)
		) {
			const _width = document.querySelector('.canvas-content')?.clientWidth || 0;
			const _time = videoBeginTime.value + event.eventTime;
			const _offset = ((_time - teachingPlanBeginTime.value) / teachingTotalTime.value) * _width;
			if (_offset >= 0 && _offset <= _width) {
				realBreakArr.value.push({
					time: _time,
					offset: _offset,
					type: event.eventType === 1004 ? 0 : 1
				});
			}
		}
	});
	// 格式化
	const _formatBreakArr: FormatBreakInfoType[] = [];
	realBreakArr.value.forEach((item, index) => {
		if (
			item.type === 0 &&
			realBreakArr.value[index + 1] &&
			realBreakArr.value[index + 1].type === 1
		) {
			_formatBreakArr.push({
				time: item.time,
				offset: item.offset,
				width: realBreakArr.value[index + 1].offset - item.offset,
				duration: realBreakArr.value[index + 1].time - item.time
			});
		}
	});
	formatBreakArr.value = _formatBreakArr;

	// 渲染dom到canvasContent（type=1时使用）
	if (canvasContent.value) {
		formatBreakArr.value.forEach((item) => {
			// 渲染矩形块
			canvasContent.value?.renderRectAtSpecifiedPosition({
				left: `${item.offset}px`,
				top: '0',
				width: `${item.width}px`
			});
			// 渲染矩形块对应的文字
			const _dom = `
						<div class="break-time-text">
							<p class="b_name">实际休息</p>
							<p class="b_time">
								${Math.floor(item.duration / 60000)}分${Math.floor(
				item.duration / 1000 - Math.floor(item.duration / 60000) * 60
			)}秒
							</p>
						</div>
					`;
			canvasContent.value?.renderDomAtSpecifiedPosition(
				_dom,
				item.offset + item.width / 2,
				35 * rate.value
			);
		});
	}
};

// 渲染课间休息时间到指定canvas（在canvas实例初始化后调用）
const renderBreakTimeToCanvas = (
	canvasInstance: DrawHorizontalAreaCanvas | null,
	selector: string
) => {
	if (!canvasInstance || !document.querySelector(selector)) {
		return;
	}

	const _width = document.querySelector(selector)?.clientWidth || 0;
	// 判断是否为interactionCanvasContent，如果是则不渲染文字
	const isInteractionCanvas = selector === '.interaction-canvas-content';

	formatBreakArr.value.forEach((item) => {
		// 重新计算基于当前canvas宽度的偏移量和宽度
		const _offset = ((item.time - teachingPlanBeginTime.value) / teachingTotalTime.value) * _width;
		const _itemWidth = (item.duration / teachingTotalTime.value) * _width;

		// 渲染矩形块
		canvasInstance.renderRectAtSpecifiedPosition({
			left: `${_offset}px`,
			top: '0',
			width: `${_itemWidth}px`
		});

		// 渲染矩形块对应的文字（interactionCanvasContent不渲染文字）
		if (!isInteractionCanvas) {
			const _dom = `
						<div class="break-time-text">
							<p class="b_name">实际休息</p>
							<p class="b_time">
								${Math.floor(item.duration / 60000)}分${Math.floor(
				item.duration / 1000 - Math.floor(item.duration / 60000) * 60
			)}秒
							</p>
						</div>
					`;
			canvasInstance.renderDomAtSpecifiedPosition(_dom, _offset + _itemWidth / 2, 35 * rate.value);
		}
	});
};

// 空白时间，这段时间内视频还没有开始录制，但已经到了课表计划开始的时间，点击这段时间，跳转到视频0秒
const blankTime = ref<number>(0);
// 数据列表（授课时长）
const durationChartList1 = ref<AudioTaskTimeTableItemType[]>([]);
// 时长信息数组（授课时长）
const timeArr1 = ref<DurationInfoType[]>([]);
// 初始化授课数据
const initTeachingData = async (data: AudioTaskTimeTableItemType[]) => {
	// 筛选课堂时间范围内的数据
	let _startObj: AudioTaskTimeTableItemType = {
		bg: 0,
		ed: 0,
		speaker: ''
	};
	let _endObj: AudioTaskTimeTableItemType = {
		bg: 0,
		ed: 0,
		speaker: ''
	};
	data = data.filter((item) => {
		// 记录开始和结束时的数据
		if (item.bg < teachingOffsetTime.value && item.ed > teachingOffsetTime.value) {
			_startObj = {
				bg: 0,
				ed: item.ed - teachingOffsetTime.value,
				speaker: item.speaker
			};
		}
		if (
			item.bg < teachingOffsetTime.value + teachingTotalTime.value &&
			item.ed > teachingOffsetTime.value + teachingTotalTime.value
		) {
			_endObj = {
				bg: item.bg - teachingOffsetTime.value,
				ed: teachingTotalTime.value,
				speaker: item.speaker
			};
		}
		// 如果一段的时长超过整个课堂的时长
		if (
			item.bg < teachingOffsetTime.value &&
			item.ed > teachingOffsetTime.value + teachingTotalTime.value
		) {
			_startObj = {
				bg: 0,
				ed: teachingTotalTime.value,
				speaker: item.speaker
			};
		}
		return (
			item.bg >= teachingOffsetTime.value &&
			item.ed <= teachingOffsetTime.value + teachingTotalTime.value
		);
	});
	// 所有时间向左平移
	data.forEach((item) => {
		item.bg -= teachingOffsetTime.value;
		item.ed -= teachingOffsetTime.value;
	});
	// 补全第一项和最后一项
	if ((!data[0] || data[0].bg !== 0) && _startObj.speaker) {
		data.unshift(_startObj);
	}
	if ((!data.at(-1) || data.at(-1)?.ed !== teachingTotalTime.value) && _endObj.speaker) {
		data.push(_endObj);
	}
	// 如果videoBeginTime大于planBeginTime，需要把所有数据向右平移差值的量
	if (
		videoBeginTime.value &&
		teachingPlanBeginTime.value &&
		videoBeginTime.value > teachingPlanBeginTime.value
	) {
		const _value = videoBeginTime.value - teachingPlanBeginTime.value;
		blankTime.value = _value;
		// 所有时间向右平移
		data.forEach((item) => {
			item.bg += _value;
			item.ed += _value;
		});
	}
	durationChartList1.value = data;
	timeArr1.value = [];
	data.forEach((item) => {
		// 去timeArr中寻找该speaker
		const timeObj = timeArr1.value.find((time) => time.speaker === item.speaker);
		if (timeObj) {
			// 计算持续最长发言时间
			const _duration = item.ed - item.bg;
			if (_duration >= 0) {
				if (_duration > timeObj.maxDurationTime) {
					timeObj.maxDurationTime = _duration;
				}
				// 计算总发言时长
				timeObj.totalTime += _duration;
			}
		} else {
			const _duration = item.ed - item.bg;
			if (_duration >= 0) {
				timeArr1.value.push({
					speaker: item.speaker,
					maxDurationTime: item.ed - item.bg,
					totalTime: _duration
				});
			}
		}
	});
	// 发言时间最长的为老师
	timeArr1.value = timeArr1.value.sort((a, b) => {
		return b.totalTime - a.totalTime;
	});
	// 给每个发言人赋予颜色
	timeArr1.value.forEach((item, index) => {
		if (index === 0) {
			item.color = '#00A8FF';
			item.isTeacher = true;
		} else {
			item.color = '#FFA24F';
			item.isTeacher = false;
		}
	});
	// 初始化图表
	if (durationChartList1.value.length) {
		nextTick(() => {
			// 绘制授课时长
			initTeachingDurationChart();
		});
	}
};

// 数据列表（授课时长）
const durationChartList = ref<AudioTaskTimeTableItemType[]>([]);
// 时长信息数组（授课时长）
const timeArr = ref<DurationInfoType[]>([]);
// 初始化互动数据
const initInteractionData = (data: AudioTaskTimeTableItemType[]) => {
	// 筛选课堂时间范围内的数据
	let _startObj: AudioTaskTimeTableItemType = {
		bg: 0,
		ed: 0,
		speaker: ''
	};
	let _endObj: AudioTaskTimeTableItemType = {
		bg: 0,
		ed: 0,
		speaker: ''
	};
	data = data.filter((item) => {
		// 记录开始和结束时的数据
		if (item.bg < teachingOffsetTime.value && item.ed > teachingOffsetTime.value) {
			_startObj = {
				bg: 0,
				ed: item.ed - teachingOffsetTime.value,
				speaker: item.speaker
			};
		}
		if (
			item.bg < teachingOffsetTime.value + teachingTotalTime.value &&
			item.ed > teachingOffsetTime.value + teachingTotalTime.value
		) {
			_endObj = {
				bg: item.bg - teachingOffsetTime.value,
				ed: teachingTotalTime.value,
				speaker: item.speaker
			};
		}
		// 如果一段的时长超过整个课堂的时长
		if (
			item.bg < teachingOffsetTime.value &&
			item.ed > teachingOffsetTime.value + teachingTotalTime.value
		) {
			_startObj = {
				bg: 0,
				ed: teachingTotalTime.value,
				speaker: item.speaker
			};
		}
		return (
			item.bg >= teachingOffsetTime.value &&
			item.ed <= teachingOffsetTime.value + teachingTotalTime.value
		);
	});
	// 所有时间向左平移
	data.forEach((item) => {
		item.bg -= teachingOffsetTime.value;
		item.ed -= teachingOffsetTime.value;
	});
	// 补全第一项和最后一项
	if ((!data[0] || data[0].bg !== 0) && _startObj.speaker) {
		data.unshift(_startObj);
	}
	if ((!data.at(-1) || data.at(-1)?.ed !== teachingTotalTime.value) && _endObj.speaker) {
		data.push(_endObj);
	}
	// 如果videoBeginTime大于planBeginTime，需要把所有数据向右平移差值的量
	if (
		videoBeginTime.value &&
		teachingPlanBeginTime.value &&
		videoBeginTime.value > teachingPlanBeginTime.value
	) {
		const _value = videoBeginTime.value - teachingPlanBeginTime.value;
		blankTime.value = _value;
		// 所有时间向右平移
		data.forEach((item) => {
			item.bg += _value;
			item.ed += _value;
		});
	}
	durationChartList.value = data;
	timeArr.value = [];
	data.forEach((item) => {
		// 去timeArr中寻找该speaker
		const timeObj = timeArr.value.find((time) => time.speaker === item.speaker);
		if (timeObj) {
			// 计算持续最长发言时间
			const _duration = item.ed - item.bg;
			if (_duration >= 0) {
				if (_duration > timeObj.maxDurationTime) {
					timeObj.maxDurationTime = _duration;
				}
				// 计算总发言时长
				timeObj.totalTime += _duration;
			}
		} else {
			const _duration = item.ed - item.bg;
			if (_duration >= 0) {
				timeArr.value.push({
					speaker: item.speaker,
					maxDurationTime: item.ed - item.bg,
					totalTime: _duration
				});
			}
		}
	});
	// 发言时间最长的为老师
	timeArr.value = timeArr.value.sort((a, b) => {
		return b.totalTime - a.totalTime;
	});
	// 给每个发言人赋予颜色
	timeArr.value.forEach((item, index) => {
		if (index === 0) {
			item.color = '#00A8FF';
			item.isTeacher = true;
		} else {
			item.color = '#FFA24F';
			item.isTeacher = false;
		}
	});
	// 初始化图表
	if (durationChartList.value.length) {
		nextTick(() => {
			// 绘制老师
			initDurationChart(0);
			// 绘制学生
			initDurationChart(1);
		});
	}
};

// 授课时长绘制的块信息数组
const teachBlockArr = ref<BlockInfoType[]>([]);
// 初始化语音时长图（授课时长模块的图）
const initTeachingDurationChart = () => {
	const _width = document.querySelector('.canvas-content')?.clientWidth || 0;
	teachBlockArr.value = [];

	durationChartList1.value.forEach((item) => {
		// 判断身份，计算颜色
		const time = timeArr1.value.find((timeObj) => timeObj.speaker === item.speaker);
		if (time?.isTeacher) {
			// 计算x坐标
			const x = Math.ceil((item.bg / teachingTotalTime.value) * _width);
			// 计算宽度
			let width = Math.floor(((item.ed - item.bg) / teachingTotalTime.value) * _width);
			if (width === 0) {
				width = 1;
			}
			if (width > 0) {
				// 保存绘制的块信息
				teachBlockArr.value.push({
					...item,
					x,
					y: 0,
					width,
					height: 30 * rate.value,
					index: teachBlockArr.value.length,
					color: time?.color as string
				});
			}
		}
	});
	// 设置绘制模式
	canvasContent.value?.setCanvasMode('fill');
	// 设置画笔样式
	canvasContent.value?.setStyle({
		color: '#00A8FF'
	});
	// 绘制矩形
	canvasContent.value?.drawRect(teachBlockArr.value);
	// 生成tooltip
	canvasContent.value?.createTooltip('time', teachingTotalTime.value, teachingPlanBeginTime.value, {
		backgroundColor: '#807d8b'
	});
	// canvas绑定鼠标事件
	canvasContent.value?.canvasBindEvent();
	// canvas绑定点击事件
	canvasContent.value?.canvasBindClickEvent(clickTeachingCanvas);
};

// 课堂讲授绘制的块信息数组
const teacherBlockArr = ref<BlockInfoType[]>([]);
// 问答互动绘制的块信息数组
const studentBlockArr = ref<BlockInfoType[]>([]);
const initDurationChart = (type: number) => {
	let _width = 0;
	if (type === 0) {
		_width = document.querySelector('.teach-canvas-content')?.clientWidth || 0;
		// 初始化实例
		teachCanvasContent.value = new DrawHorizontalAreaCanvas(
			document.querySelector('.teach-canvas-content')
		);
		// 创建画布
		teachCanvasContent.value.createCanvas({
			'border-radius': '1px',
			'background-color': 'rgba(0, 168, 255, 0.1)',
			cursor: 'pointer'
		});
	} else if (type === 1) {
		_width = document.querySelector('.interaction-canvas-content')?.clientWidth || 0;
		// 初始化实例
		interactionCanvasContent.value = new DrawHorizontalAreaCanvas(
			document.querySelector('.interaction-canvas-content')
		);
		// 创建画布
		interactionCanvasContent.value.createCanvas({
			'border-radius': '1px',
			'background-color': 'rgba(255, 162, 79, 0.1)',
			cursor: 'pointer'
		});
	}

	if (type === 0) {
		teacherBlockArr.value = [];
	} else {
		studentBlockArr.value = [];
	}
	durationChartList.value.forEach((item) => {
		// 判断身份，计算颜色
		const time = timeArr.value.find((timeObj) => timeObj.speaker === item.speaker);
		if ((type === 0 && time?.isTeacher) || (type === 1 && !time?.isTeacher)) {
			// 计算x坐标
			const x = Math.ceil((item.bg / teachingTotalTime.value) * _width);
			// 计算宽度
			let width = Math.floor(((item.ed - item.bg) / teachingTotalTime.value) * _width);
			if (width === 0) {
				width = 1;
			}
			if (width > 0) {
				// 保存绘制的块信息
				if (type === 0) {
					teacherBlockArr.value.push({
						...item,
						x,
						y: 0,
						width,
						height: 30 * rate.value,
						index: teacherBlockArr.value.length,
						color: time?.color as string
					});
				} else {
					studentBlockArr.value.push({
						...item,
						x,
						y: 0,
						width,
						height: 30 * rate.value,
						index: studentBlockArr.value.length,
						color: time?.color as string
					});
				}
			}
		}
	});
	if (type === 0) {
		// 设置绘制模式
		teachCanvasContent.value?.setCanvasMode('fill');
		// 设置画笔样式
		teachCanvasContent.value?.setStyle({
			color: '#00A8FF'
		});
		// 绘制矩形
		teachCanvasContent.value?.drawRect(teacherBlockArr.value);
		// 生成tooltip
		teachCanvasContent.value?.createTooltip(
			'time',
			teachingTotalTime.value,
			teachingPlanBeginTime.value,
			{
				backgroundColor: '#807d8b'
			}
		);
		// canvas绑定鼠标事件
		teachCanvasContent.value?.canvasBindEvent();
		// canvas绑定点击事件
		teachCanvasContent.value?.canvasBindClickEvent(clickCanvas, 0);
		// 渲染课间休息时间
		renderBreakTimeToCanvas(teachCanvasContent.value, '.teach-canvas-content');
	} else {
		// 设置绘制模式
		interactionCanvasContent.value?.setCanvasMode('fill');
		// 设置画笔样式
		interactionCanvasContent.value?.setStyle({
			color: '#FFA24F'
		});
		// 绘制矩形
		interactionCanvasContent.value?.drawRect(studentBlockArr.value);
		// 生成tooltip
		interactionCanvasContent.value?.createTooltip(
			'time',
			teachingTotalTime.value,
			teachingPlanBeginTime.value,
			{
				backgroundColor: '#807d8b'
			}
		);
		// canvas绑定鼠标事件
		interactionCanvasContent.value?.canvasBindEvent();
		// canvas绑定点击事件
		interactionCanvasContent.value?.canvasBindClickEvent(clickCanvas, 1);
		// 渲染课间休息时间
		renderBreakTimeToCanvas(interactionCanvasContent.value, '.interaction-canvas-content');
	}
};

// 点击授课时长canvas
const clickTeachingCanvas = (e: MouseEvent, _currentBlock: BlockInfoType | null) => {
	if (!_currentBlock) {
		const canvas = document.querySelector('.canvas-content');
		const _canvasWidth = canvas?.clientWidth || 0;
		// 计算时间(s)
		const _offsetX = e.offsetX > _canvasWidth ? _canvasWidth : e.offsetX;
		let _currentTime =
			(_offsetX / _canvasWidth) * teachingTotalTime.value < 0
				? teachingOffsetTime.value
				: (_offsetX / _canvasWidth) * teachingTotalTime.value + teachingOffsetTime.value;
		// 在空白时间内，跳转到视频0秒
		_currentTime = (_currentTime - blankTime.value) / 1000;
		emit('changeVideoTime', _currentTime);
	} else {
		const _currentTime = (_currentBlock.bg + teachingOffsetTime.value - blankTime.value) / 1000;
		emit('changeVideoTime', _currentTime);
	}
};

// 点击canvas type=0老师 type=1学生
const clickCanvas = (e: MouseEvent, _currentBlock: BlockInfoType | null, type: number) => {
	if (!_currentBlock) {
		let canvas;
		if (type === 0) {
			canvas = document.querySelector('.teach-canvas-content');
		} else {
			canvas = document.querySelector('.interaction-canvas-content');
		}
		const _canvasWidth = canvas?.clientWidth || 0;
		// 计算时间(s)
		const _offsetX = e.offsetX > _canvasWidth ? _canvasWidth : e.offsetX;
		let _currentTime =
			(_offsetX / _canvasWidth) * teachingTotalTime.value < 0
				? teachingOffsetTime.value
				: (_offsetX / _canvasWidth) * teachingTotalTime.value + teachingOffsetTime.value;
		// 在空白时间内，跳转到视频0秒
		_currentTime = (_currentTime - blankTime.value) / 1000;
		emit('changeVideoTime', _currentTime);
	} else {
		const _currentTime = (_currentBlock.bg + teachingOffsetTime.value - blankTime.value) / 1000;
		emit('changeVideoTime', _currentTime);
	}
};
</script>

<style lang="scss" scoped>
.teaching-time-wrapper {
	.box-wrap {
		padding: 7.4rem 2rem 4.3rem;
		background-color: rgba($color: $bg-block-color-primary, $alpha: 0.9);
	}

	.voice-canvas-wrap {
		display: flex;
		align-items: center;
		width: 100%;

		.in-class,
		.out-class {
			font-size: $font-size-small-1;
			color: $text-color-secondary;
		}

		.canvas-content {
			flex: 1;
			position: relative;
			z-index: 999;
			margin: 0 1rem;
			height: 3rem;
		}
	}

	:deep(.break-time-text) {
		transform: translateX(-50%);

		p {
			font-size: $font-size-small-1;
			white-space: nowrap;
			color: $text-color-success;
			line-height: 1;
		}

		p.b_name {
			margin-bottom: 0.5rem;
		}
	}

	:deep(.begin-time),
	:deep(.end-time) {
		display: flex;
		flex-direction: column;
		align-items: center;
		transform: translateX(-50%);
		font-size: $font-size-small-1;
		color: $text-color-brand;
		line-height: 1;
		white-space: nowrap;
		pointer-events: none;

		p {
			margin-bottom: 0.5rem;
		}

		.circle {
			width: 5px;
			height: 5px;
			background-color: $color-brand;
			border-radius: 50%;
		}

		.line {
			width: 0;
			height: calc(3rem + 5px + 0.9rem);
			border-left: 1px dashed rgba($color: $color-brand, $alpha: 0.4);
		}

		&.blue {
			color: $text-color-brand;

			.circle {
				background-color: $color-brand;
			}

			.line {
				border-color: rgba($color: $color-brand, $alpha: 0.4);
			}
		}

		&.red {
			color: $text-color-danger;

			.circle {
				background-color: $color-danger;
			}

			.line {
				border-color: rgba($color: $color-danger, $alpha: 0.4);
			}
		}
	}

	:deep(.timeline-item) {
		display: flex;
		flex-direction: column;
		align-items: center;
		transform: translateX(-50%) translateY(calc(100% - 3rem));
		font-size: $font-size-small-1;
		color: $text-color-secondary;
		line-height: 1;
		white-space: nowrap;
		pointer-events: none;

		p {
			margin-top: 0.5rem;
		}

		.circle {
			width: 5px;
			height: 5px;
			background-color: transparent;
			border-radius: 50%;
		}

		.line {
			width: 0;
			height: calc(3rem + 5px + 0.5rem);
			border-left: 1px dashed transparent;
		}

		&.timeline-item-0,
		&.timeline-item-6 {
			.circle {
				background-color: $color-success;
			}

			.line {
				border-left: 1px dashed rgba($color: $color-success, $alpha: 0.4);
			}
		}
	}

	:deep(.section-item) {
		height: 3rem;
		background-color: rgba($color: $color-success, $alpha: 0.3);
	}

	:deep(.canvas-tooltip) {
		position: absolute;
		display: none;
		top: -3rem;
		left: 0;
		transform: translateX(-50%);
		padding: 0 0.5rem;
		height: 2rem;
		font-size: $font-size-small-1;
		line-height: 2rem;
		background-color: $bg-block-color-dark;
		border-radius: 0.3rem;
		color: #ffffff;
		z-index: 999;
	}

	.canvas-wrap {
		margin-top: 1.6rem;
		padding-bottom: 5rem;
		background-color: rgba($color: $bg-block-color-primary, $alpha: 0.9);

		.title-wrap {
			padding: 1.8rem 0 3rem 2.6rem;
			display: flex;
			align-items: center;

			.line {
				margin-right: 0.8rem;
				width: 0.4rem;
				height: $font-size-small-1;
				background: $color-brand;
				border-radius: 0.2rem;
			}

			p {
				font-size: $font-size-base;
				color: $text-color-brand;
			}
		}

		.teach-canvas-wrap,
		.interaction-canvas-wrap {
			padding: 0 3.3rem;
			display: flex;
			align-items: center;
			width: 100%;

			.left {
				margin-right: 1.5rem;
				font-size: $font-size-small-1;
				color: #00a8ff;
				line-height: 1;
			}
			.teach-canvas-content,
			.interaction-canvas-content {
				position: relative;
				z-index: 999;
				flex: 1;
				height: 3rem;

				.timeline-item {
					position: absolute;
					bottom: -2.5rem;
					transform: translateX(-50%);
					font-size: $font-size-small-2;
					color: $text-color-secondary;
					white-space: nowrap;

					&.timeline-item-0 {
						left: 0;
					}

					&.timeline-item-1 {
						left: 16.67%;
					}

					&.timeline-item-2 {
						left: 33.33%;
					}

					&.timeline-item-3 {
						left: 50%;
					}

					&.timeline-item-4 {
						left: 66.67%;
					}

					&.timeline-item-5 {
						left: 83.33%;
					}

					&.timeline-item-6 {
						left: 100%;
					}
				}
			}
		}

		.interaction-canvas-wrap {
			margin-top: 1.7rem;

			.left {
				color: #ffa24f;
			}
		}

		.empty-detail {
			position: relative;
		}
	}
}
</style>
